package cn.edu.bupt.freewings.forum.common.format;

import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.DocType;

import com.google.protobuf.Message;
import com.google.protobuf.Descriptors;

import cn.edu.bupt.freewings.forum.common.UserType;
import org.jdom.output.XMLOutputter;
import org.jdom.output.Format;

public class XMLFormatter {
	static public Document toXMLDocument(Message protoMessage) {
		Document doc = new Document();
		Element root = new Element(protoMessage.getDescriptorForType().getName()
				.toLowerCase());
		doc.setRootElement(root);
		addChildren(root, protoMessage.getAllFields());
		return doc;
	}

	static protected void addChildren(Element parent,
			Map<Descriptors.FieldDescriptor, Object> fields) {
		for (Map.Entry<Descriptors.FieldDescriptor, Object> entry : fields
				.entrySet()) {
			addChild(parent, entry.getKey(), entry.getValue());
		}
	}

	@SuppressWarnings("unchecked")
	static protected void addChild(Element parent,
			Descriptors.FieldDescriptor fieldDesc, Object value) {
		if (fieldDesc.isRepeated()) {
			List list = (List) value;
			if (fieldDesc.getType() != Descriptors.FieldDescriptor.Type.MESSAGE
					&& fieldDesc.getType() != Descriptors.FieldDescriptor.Type.GROUP) {
				for (Object o : list) {
					Element element = new Element(fieldDesc.getName());
					element.addContent(o.toString());
					parent.addContent(element);
				}
			} else if (fieldDesc.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
				for (Object o : list) {
					Element element = new Element(fieldDesc.getName());
					Message msg = (Message) o;
					addChildren(element, msg.getAllFields());
					parent.addContent(element);
				}
			} else {

			}
		} else {
			Element element = new Element(fieldDesc.getName());
			if (fieldDesc.getType() != Descriptors.FieldDescriptor.Type.MESSAGE
					&& fieldDesc.getType() != Descriptors.FieldDescriptor.Type.GROUP) {
				element.addContent(value.toString());
			} else if (fieldDesc.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
				Message msg = (Message) value;
				addChildren(element, msg.getAllFields());
			}
			parent.addContent(element);
		}
	}

	public static void main(String args[]) throws Exception{
		UserType.User.Builder builder = UserType.User.newBuilder();
		builder.setId(1).setName("hubaiyu").setNickName("baiyu").setPassword(
				"diuowsk").setTag("d");
		UserType.User user = builder.build();
		//System.out.println(user);
		XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
		outputter.output(toXMLDocument((Message)user), System.out);
	}
}
